home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 25 / Cream of the Crop 25.iso / utility / ffe101.zip / GRAPH.SWG / 0008_ICON.pas < prev    next >
Pascal/Delphi Source File  |  1996-09-04  |  5KB  |  133 lines

  1.  
  2. Header
  3. }
  4. TIconHeader = record
  5.   idReserved: Word; (* Always set to 0 *)
  6.   idType: Word;     (* Always set to 1 *)
  7.   idCount: Word;    (* Number of icon images *)
  8.   (* immediately followed by idCount TIconDirEntries *)
  9. end;
  10. {
  11.  
  12. A  .ICO  file can contain several icon  images. Each image can differ in
  13. size, resolution and color format.
  14.  
  15. }
  16. TIconDirEntry = record
  17.   bWidth: Byte;          (* Width *)
  18.   bHeight: Byte;         (* Height *)
  19.   bColorCount: Byte;     (* Nr. of colors used, see below *)
  20.   bReserved: Byte;       (* not used, 0 *)
  21.   wPlanes: Word;         (* not used, 0 *)
  22.   wBitCount: Word;       (* not used, 0 *)
  23.   dwBytesInRes: Longint; (* total number of bytes in images *)
  24.   dwImageOffset: Longint;(* location of image from the beginning of file *)
  25. end;
  26.  
  27. {
  28. bColorCount  refers to the number of  palette entries in the image data.
  29. For  the most common icon type (32x32 pixels, 16 colors) the first three
  30. fields would be 32, 32 and 16 resp.
  31.  
  32. dwBytesInRes  is the total number of  bytes in the image data (including
  33. palette  data!).  dwImageOffset is an offset  (from the beginning of the
  34. file) to the image data.
  35.  
  36.  
  37. Image data
  38.  
  39. The  icon  file  stores image data  in  the so-called device independent
  40. bitmap  (DIB) format. It's supposed to be fairly device independent :-).
  41. The  actual pixel data is preceded  by two "structures": the bitmap info
  42. header and the palette data.
  43.  
  44. First  the bitmap info header (pasted  from the BP WinSDK help, comments
  45. are mine):
  46. }
  47. TBitmapInfoHeader = record
  48.   biSize: Longint;    (* sizeof(TBitmapInfoHeader *)
  49.   biWidth: Longint;   (* width of bitmap *)
  50.   biHeight: Longint;  (* height of bitmap, see notes *)
  51.   biPlanes: Word;     (* planes, always 1 *)
  52.   biBitCount: Word;   (* number of color bits *)
  53.   biCompression: Longint; (* compression used, 0 *)
  54.   biSizeImage: Longint;   (* size of the pixel data, see notes *)
  55.   biXPelsPerMeter: Longint; (* not used, 0 *)
  56.   biYPelsPerMeter: Longint; (* not used, 0 *)
  57.   biClrUsed: Longint;       (* nr of colors used, set to 0 *)
  58.   biClrImportant: Longint;  (* important colors, set to 0 *)
  59. end;
  60.  
  61. {
  62. biBitcount  contains  the number of color bits  per pixel. If it's 4, it
  63. means  a  pixel can have 16 colors  (2 shl 4). biBitcount also refers to
  64. how  a  pixel is "coded" in the pixel  data.  If biBitcount is 4 a pixel
  65. takes  4 bits of an image byte. If it's 8 (256 possible colors), a pixel
  66. is a byte.
  67.  
  68. As  you  perhaps know, icons are  created by combining two bitmap masks:
  69. the XOR-mask and the monochrome AND-mask. To draw an icon you first copy
  70. the  mask to the screen with an AND operator, then you copy the XOR-mask
  71. with an XOR operator.
  72.  
  73. Therefore  the  biHeight field is set  to  2 * TIconDirEntry.bHeight and
  74. biSizeImage is set to the size of the AND plus the XOR mask (ofcourse in
  75. bytes).  For example, for a 32x32 16 color icon biHeight would be 64 and
  76. biSizeImage 512 + 128.
  77.  
  78. OK. How do you determine the size of the masks?
  79.  
  80. XOR  mask: (TIconDirEntry.bWidth * TIconDirEntry.bHeight * biBitCount) /
  81. 8 AND mask: (TIconDirEntry.bWidth * TIconDirEntry.bHeight) / 8
  82.  
  83. The palette data
  84.  
  85. The  bitmap info header is followed by a table with palette entries. The
  86. actual  pixel  data refer to this table.  So  when a pixel has color 13,
  87. look  at  palette  entry number 13 to  get  the actual RGB color for the
  88. pixel.  At this moment Windows just  supports 2 (monochrome), 16 and 256
  89. colors, so there's always a palette table.
  90.  
  91. An entry in the palette table has the following format: }
  92.  
  93. TRGBQuad = record
  94.   rgbBlue: Byte;      (* blue component of color *)
  95.   rgbGreen: Byte;     (* green component of color *)
  96.   rgbRed: Byte;       (* red component of color *)
  97.   rgbReserved: Byte;  (* reserved, 0 *)
  98. end;
  99.  
  100. {
  101. For  Windows programmers: this record is *not* equivalent to a TColorRef
  102. (or  COLORREF).  If you forget this,  you'll  get some odd colored icons
  103. :-).
  104.  
  105. An  icon  has  TIconDirEntry.bColorCount palette  entries.  So there are
  106. sizeof(TRGBQuad) * TIconDirEntry.bColorCount bytes in the palette.
  107.  
  108. The  monochrome AND mask does _not_ have a palette table. A 1 bit in the
  109. AND  mask's pixel data means a _white_  pixel on-screen. A 0 bit means a
  110. black pixel.
  111.  
  112. On  the other hand, the pixel data of monochrome icons _are_ preceded by
  113. a palette table.
  114.  
  115.  
  116. Pixel data
  117.  
  118. Now  to  the real nitty-gritty. Immediately  after the palette data, the
  119. pixel data follow. Remember: the pixel data contain both the XOR and AND
  120. bits.
  121.  
  122. There's  something odd with the storage of the mask bits: both mask data
  123. are  stored in bottom up format. For example: in a 32 x 32 16 color icon
  124. the  first 32 nibbles belong actually to  the last pixel row. The second
  125. 32  nibbles form the last - 1 pixel row. And so on. Retrieving pixels is
  126. a  little  bit  hard.  Just keep  track  of  the biBitCount value. Write
  127. different  functions  for monochrome, 16 and  256  color icons or keep a
  128. running  bit  mask ready. In Windows creating  an icon from .ICO file is
  129. rather  easy,  call  the  CreateDIBitmap  function  twice  (for  the AND
  130. mask/XOR  mask).  Then call GetBitmapBits  to  retrieve the bitmap data.
  131. Under  DOS you have to do a little more: e.g. translation of RGB colors.
  132. }
  133.